#pragma once
#include <xpam/ui/notify_icon.h>
#include <xpam/system/user_io.h>
#include <algorithm>

namespace xpam
{
    namespace ui
    {
        namespace _notify_icon_internal
        {
            int message_id = 0xf00d;

            LRESULT CALLBACK procedure(HWND h, UINT m, WPARAM w, LPARAM l)
            {
                notify_icon * tthis = (notify_icon*)w;
                //notify_icon * tthis = (notify_icon*)::GetWindowLongA(h, GWL_ID);
                if (m == message_id && tthis)
                {
                    int n_event = LOWORD(l);

                    if (false) { }
                    else if (n_event == WM_LBUTTONDOWN)
                    {
                        tthis->on_left_mouse_down(tthis, xpam::system::user_io::cursor_position());
                    }
                    else if (n_event == WM_LBUTTONUP)
                    {
                        tthis->on_left_mouse_up(tthis, xpam::system::user_io::cursor_position());
                    }
                    else if (n_event == WM_LBUTTONDBLCLK)
                    {
                        tthis->on_left_mouse_dblclk(tthis, xpam::system::user_io::cursor_position());
                    }
                    else if (n_event == WM_RBUTTONDOWN)
                    {
                        tthis->on_rigth_mouse_down(tthis, xpam::system::user_io::cursor_position());
                    }
                    else if (n_event == WM_RBUTTONUP)
                    {
                        tthis->on_rigth_mouse_up(tthis, xpam::system::user_io::cursor_position());
                    }
                    else if (n_event == WM_RBUTTONDBLCLK)
                    {
                        tthis->on_rigth_mouse_dblclk(tthis, xpam::system::user_io::cursor_position());
                    }
                    return true;
                }
                return false;
            }
        }

        notify_icon::notify_icon(const std::string & tip)
        {
            user_data = 0;
            _tip = tip;
            _message_wnd.create<char, int>("Message", "", 0, 0, xpam::size<unsigned int>(0,0));
            ::SetWindowLongA((HWND)_message_wnd.get_internal_handle(), GWL_WNDPROC, (LONG)_notify_icon_internal::procedure);
        }

        notify_icon::~notify_icon()
        {
            remove();
        }

        bool notify_icon::add()
        {
            NOTIFYICONDATAA data;
            data.cbSize = sizeof(data);
            data.hWnd = (HWND)_message_wnd.get_internal_handle();
            data.uID = (int)this;
            data.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
            data.hIcon = LoadIcon(NULL, IDI_ASTERISK);
            data.uCallbackMessage = _notify_icon_internal::message_id;
            std::fill_n(data.szTip, 64, 0);
            std::copy(_tip.begin(), _tip.begin() + std::min<int>(_tip.size(), 63), data.szTip);
            return TRUE == Shell_NotifyIconA(NIM_ADD, &data);
        }

        void notify_icon::remove()
        {
            NOTIFYICONDATAA data;
            data.cbSize = sizeof(data);
            data.hWnd = (HWND)_message_wnd.get_internal_handle();
            data.uID = (int)this;
            Shell_NotifyIconA(NIM_DELETE, &data);
        }

        void notify_icon::modify()
        {
            throw xpam::exception() << "not implemented";
        }
    }
}